import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class PlayGame extends JPanel {
    public static final int START = 0;
    public static final int RUNNING = 1;
    public static final int PAUSE = 2;
    public static final int LOSER = 3;
    public static final int WIN = 4;
    private int state = RUNNING;

    private Sheep sheep;
    private Wolf[] wolfs = new Wolf[0];;
    private Attack[] attacks = new Attack[0];
    private Box[] boxes = {};
    private int level = 1;
    private int totalwolf = 30;
    private int killofwolfs = 0;
    private int score = 0;
    JPanel playgame = this;
    JFrame jFrame;

    PlayGame(JFrame jFrame,Sheep sheep){
        this.jFrame = jFrame;
        this.sheep = sheep;
    }


    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(new Color(255,138,89));
        g.setFont(new Font("黑体",Font.BOLD, 30));

        if (level==1)g.drawImage(Images.background_1,0,0,null);
        else if (level==2)g.drawImage(Images.background_2,0,0,null);
        else if (level==3)g.drawImage(Images.background_3,0,0,null);
        if (sheep.isdroping||sheep.isjumping)g.drawImage(Images.rocket[enterIndex%2],sheep.x-6,sheep.y-10,null);
        g.drawImage(sheep.getImage(),sheep.x,sheep.y,null);

        if (sheep.attackmode==0&&(sheep.ismoving||sheep.isattacking)){
            if (sheep.attackdirection==TotalObject.RIGHT)g.drawImage(Images.nearattacktool[0],sheep.x+50,sheep.y+10,null);
            else g.drawImage(Images.nearattacktool[1],sheep.x-20,sheep.y+10,null);
        }

        if (sheep.attackmode==1&&(sheep.ismoving||sheep.isattacking)){
            if (sheep.attackdirection==TotalObject.RIGHT)g.drawImage(Images.farattacktool[0],sheep.x+50,sheep.y+10,null);
            else g.drawImage(Images.farattacktool[1],sheep.x-20,sheep.y+10,null);
        }

        if (sheep.attackmode == 0)g.drawImage(Images.select,20,100,null);
        else if (sheep.attackmode == 1)g.drawImage(Images.select,125,100,null);
        if (sheep.iswudi())g.drawImage(Images.protectivecover,sheep.x-20,sheep.y-15,null);
        g.drawString(""+score,810,45);
        g.drawString(""+level,810,90);
        for (int i=0;i<wolfs.length;i++){
            if (wolfs[i].isenter == false)continue;
            if (wolfs[i].isdroping){
                g.drawImage(wolfs[i].getImage(),wolfs[i].x,wolfs[i].y-100,null);
            }
            else g.drawImage(wolfs[i].getImage(),wolfs[i].x,wolfs[i].y,null);
        }

        for (int i=0;i<boxes.length;i++){
            if (boxes[i].isenter == false)continue;
            g.drawImage(boxes[i].getImage(),boxes[i].x,boxes[i].y,null);
        }

        for (int i = 0;i<attacks.length;i++){
            g.drawImage(Images.bullet,attacks[i].x,attacks[i].y,null);
        }
        g.drawImage(Images.scoreandround,660,20,null);
        g.drawImage(wolfPlane.getImage(),wolfPlane.x,wolfPlane.y,null);
        g.drawImage(sheepPlane.getImage(),sheepPlane.x,sheepPlane.y,null);
        g.drawImage(sheep.getportraitImage(),10,10,null);
        g.setColor(Color.RED);
        g.fillRect(111,28, (int) ((sheep.life/10.0)*98),13);
        g.setColor(new Color(86,190,250));
        g.fillRect(111,61, (int) ((sheep.numberofbullets/100.0)*98),13);
        if (state==PAUSE)g.drawImage(Images.pause_back,240,150,null);
        if (state==RUNNING)g.drawImage(Images.pause,900,30,null);
        if (state==WIN){
            g.drawImage(Images.win_back,0,0,null);
        }
        else if (state==LOSER){
            g.drawImage(Images.loser_back,0,0,null);
        }
    }

    public void action() {
        makewolfs();
        makeboxs();
        this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                switch(e.getKeyCode()) {
                    case KeyEvent.VK_W:
                        break;
                    case KeyEvent.VK_S:
                        sheep.setDirection(TotalObject.DOWN);
                        break;
                    case KeyEvent.VK_A:
                        sheep.setDirection(TotalObject.LEFT);
                        break;
                    case KeyEvent.VK_D:
                        sheep.setDirection(TotalObject.RIGHT);
                        break;

                    case KeyEvent.VK_J:
                        if (sheep.canjump)sheep.letjump();
                        break;
                    case KeyEvent.VK_K:
                        if (sheep.attackmode==1&&sheep.numberofbullets==0)break;
                        attackAction();
                        break;
                    case KeyEvent.VK_U:
                        sheep.changeattackmode();
                }
            }
            public void keyReleased(KeyEvent e){
                switch(e.getKeyCode()) {
                    case KeyEvent.VK_W:
                        sheep.letstop();
                        break;
                    case KeyEvent.VK_S:
                        sheep.letstop();
                        break;
                    case KeyEvent.VK_D:
                        sheep.letstop();
                        break;
                    case KeyEvent.VK_A:
                        sheep.letstop();
                        break;
                    case KeyEvent.VK_J:
                        break;
                }
            }

        });
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {

                super.mouseClicked(e);
                if (state==WIN||state==LOSER){
                    System.out.println("s");
                    playgame.setVisible(false);
                    try {
                        jFrame.add(new LaunchPage(jFrame));
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                }
                if (e.getX()>587&&e.getX()<687&&e.getY()>238&&e.getY()<356)state = RUNNING;
                if (e.getX()>295&&e.getX()<390&&e.getY()>240&&e.getY()<340) {
                    if (state==PAUSE){
                        playgame.setVisible(false);
                        try {
                            jFrame.add(new LaunchPage(jFrame));
                        } catch (IOException ioException) {
                            ioException.printStackTrace();
                        }
                    }
                }
                if (e.getX()>900&&e.getX()<960&&e.getY()>30&&e.getY()<90) {
                    state = PAUSE;
                }

            }
        });
        final Timer timer = new Timer();
        int interval = 16;
        timer.schedule(new TimerTask() {
            public void run() {

                if(state==RUNNING) {
                    heroBangAction();
                    sheep.step();
                    if (sheep.isjumping)sheep.jump();
                    if (sheep.isdroping)sheep.drop();

                    enterAction();
                    stepAction();
                    attackBangAction();
                    outOfBoundsAction();
                    clearAction();
                    if (wolfs.length==0)makewolfs();
                    if (boxes.length==0)makeboxs();
                }
                else if (state==LOSER){
                    timer.cancel();
                    System.out.println("gameover");
                }
                else if(state == WIN){
                    timer.cancel();
                    System.out.println("win");
                }
                if (killofwolfs>=10&&killofwolfs<20){
                    level=2;
                }
                if (killofwolfs>=20){
                    level=3;
                }
                if (killofwolfs>=30){
                    state=WIN;
                }
                if (sheep.life==0){
                    state = LOSER;
                }

                repaint();

            }
        },interval,interval);
        repaint();


    }

    private void stepAction() {
        for (int i=0;i<wolfs.length;i++){
            if (wolfs[i].isdroping)wolfs[i].drop();
            else wolfs[i].step(sheep);
        }

        for(int i=0;i<attacks.length;i++) {
            attacks[i].step();
        }
        for (int i=0;i<boxes.length;i++){
            boxes[i].drop();
        }
        wolfPlane.move();
        sheepPlane.move();
    }

    private void makewolfs(){
        for (int i = 0;i<5;i++){
            Wolf obj = nextOne();
            wolfs = Arrays.copyOf(wolfs,wolfs.length+1);
            wolfs[wolfs.length-1] = obj;
        }
    }

    private void makeboxs(){
        for (int i = 0;i<2;i++){
            Box obj = nextOnebox();
            boxes = Arrays.copyOf(boxes,boxes.length+1);
            boxes[boxes.length-1] = obj;
        }
    }

    public SheepPlane sheepPlane = new SheepPlane();
    public WolfPlane wolfPlane = new WolfPlane();

    private int enterIndex = 0;

    public void enterAction() {
        for (int i = 0;i<wolfs.length;i++){
            if (wolfs[i].x==wolfPlane.x){
                wolfs[i].isenter = true;
            }
        }
        for (int i = 0;i<boxes.length;i++){
            if (boxes[i].x==sheepPlane.x){
                boxes[i].isenter = true;
            }
        }
    }

    private Box nextOnebox() {
        Random rand = new Random();
        int type = rand.nextInt(10);
        int x = rand.nextInt(300)*3;
        int y = 40;
        if(type<7) {
            return new BulletBox(x,y);
        }else {
            return new LifeBox(x,y);
        }
    }


    private Wolf nextOne() {
        Random rand = new Random();
        int type = rand.nextInt(10);
        int x = rand.nextInt(300)*3;
        int y = 40;
        if(type<6) {
            return new SmallWolf(x,y);
        }else if(type<8) {
            return new Bigwolf(x,y);
        }else {
            return new BigBoss(x,y);
        }
    }

    //角色碰到物体
    public void heroBangAction()   {
        for (int i=0;i<wolfs.length;i++){
            if (sheep.isHit(wolfs[i])&&sheep.isdroping){
                wolfs[i].reducelife();
                if (wolfs[i].level==3&&!sheep.iswudi())sheep.reducelife();
                sheep.letjump();
            }
            else if (sheep.isHit(wolfs[i])&&!sheep.isdroping&&!sheep.iswudi()&&!sheep.isjumping){
                sheep.reducelife();
            }
            if (sheep.isHit(wolfs[i])&&((sheep.movedirection==TotalObject.RIGHT&&wolfs[i].x>sheep.x)||(sheep.movedirection==TotalObject.LEFT&&wolfs[i].x<sheep.x))){
                sheep.letstop();
            }
        }

        for (int i=0;i<boxes.length;i++){
            if (sheep.isHit(boxes[i])){
                if (boxes[i] instanceof LifeBox&&sheep.life<10)sheep.life++;
                else if (boxes[i] instanceof BulletBox&&sheep.numberofbullets<100){
                    sheep.numberofbullets+=10;
                    if (sheep.numberofbullets>100)sheep.numberofbullets=100;
                }
                boxes[i].reducelife();
            }
        }
    }

    //超出边界
    public void outOfBoundsAction() {
        for (int i = 0;i<attacks.length;i++){
            if (attacks[i].x<0||attacks[i].x>1000){
                attacks[i].goDead();
            }
        }
    }

    public void attackBangAction() {
        for (int i = 0;i<attacks.length;i++){
            for (int j=0;j<wolfs.length;j++){
                if (wolfs[j].isHit(attacks[i])&&!attacks[i].isdead()){
                    wolfs[j].reducelife();
                    attacks[i].goDead();
                }
            }
        }
    }

    public void attackAction() {
        Attack attack = sheep.attack();
        attacks = Arrays.copyOf(attacks,attacks.length+1);
        attacks[attacks.length-1] = attack;

    }


    private void clearAction(){
        for (int i=0;i<wolfs.length;i++){
            if (wolfs[i].isdead()){
                if (wolfs[i] instanceof SmallWolf)score+=10;
                else if (wolfs[i] instanceof Bigwolf)score+=20;
                else if (wolfs[i] instanceof BigBoss)score+=30;
                wolfs[i] = wolfs[wolfs.length-1];
                wolfs = Arrays.copyOf(wolfs,wolfs.length-1);
                killofwolfs++;
            }
        }

        for(int i=0;i<attacks.length;i++) {
            if (attacks[i].attacktype==0||attacks[i].life==0){
                attacks[i] = attacks[attacks.length-1];
                attacks = Arrays.copyOf(attacks,attacks.length-1);
            }

        }

        for(int i=0;i<boxes.length;i++) {
            if (boxes[i].isdead()){
                score+=10;
                boxes[i] = boxes[boxes.length-1];
                boxes = Arrays.copyOf(boxes,boxes.length-1);
            }

        }

    }


}
